#include "s_nor_flash_user.h"
#include "s_norflash_driver.h"

#include <stdio.h>
#include <string.h>

static NorFlash_Handle norflash;
//////////////////////////////////////////////////////////////////////////////////
#include "h_stm32_hal_defines.h"
#include "h_stm32_hal_spi.h"

#define S_NOR_FLASH_USER_CS_PORT            GPIOB
#define S_NOR_FLASH_USER_CS_PIN             GPIO_PIN_6

static void s_nor_flash_user_spi_cs_enable(void)
{
    HAL_GPIO_WritePin(S_NOR_FLASH_USER_CS_PORT, S_NOR_FLASH_USER_CS_PIN, GPIO_PIN_RESET);
}

static void s_nor_flash_user_spi_cs_disable(void)
{
    HAL_GPIO_WritePin(S_NOR_FLASH_USER_CS_PORT, S_NOR_FLASH_USER_CS_PIN, GPIO_PIN_SET);
}

static void s_nor_flash_user_spi_cs_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitStruct.Pin = S_NOR_FLASH_USER_CS_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(S_NOR_FLASH_USER_CS_PORT, &GPIO_InitStruct);

    s_nor_flash_user_spi_cs_disable();

    return h_stm32_hal_spi_ok;
}

static NorFlash_Result s_nor_flash_user_spi_write(const unsigned char *data, unsigned short len)
{
    return (NorFlash_Result)h_stm32_hal_spi1_write((unsigned char *)data, len);
}

static NorFlash_Result s_nor_flash_user_spi_read(unsigned char *data, unsigned short len)
{
    return (NorFlash_Result)h_stm32_hal_spi1_read((unsigned char *)data, len);
}
//////////////////////////////////////////////////////////////////////////////////

signed char s_nor_flash_user_init(void)
{
    // signed char rslt = 0;

    // norflash.manId = 0xEF;
    // norflash.devId = 0x14;
    // norflash.devSize = 2097152; //16Mb
    // norflash.sectorCount = 512;//512;//512;
    // norflash.pageSize = 256;
    // norflash.sectorSize = 4096;//4096;
    // norflash.blockSize = 1;//65536;

    norflash.manId = 0xEF;
    norflash.devId = 0x17;
    norflash.devSize = 2097152; //16Mb
    norflash.sectorCount = 512;//512;//512;
    norflash.pageSize = 256;
    norflash.sectorSize = 4096;//4096;
    norflash.blockSize = 1;//65536;

    s_nor_flash_user_spi_cs_init();

    norflash.norflash_select = &s_nor_flash_user_spi_cs_enable;
    norflash.norflash_deselect = &s_nor_flash_user_spi_cs_disable;
    norflash.norflash_write = &s_nor_flash_user_spi_write;
    norflash.norflash_read = &s_nor_flash_user_spi_read;

    // rslt = S_NorFlash_Open(norflash);
    // rslt += S_NorFlash_Close(norflash);
    return 0;
}

signed char s_nor_flash_user_open(void)
{
    return (signed char)S_NorFlash_Open(norflash);
    // return 0;
}

signed char s_nor_flash_user_close(void)
{
    return (signed char)S_NorFlash_Close(norflash);
    // return 0;
}

signed char s_nor_flash_user_erase_chip(void)
{
    return S_NorFlash_ChipErase(norflash);
}

signed char s_nor_flash_user_erase(unsigned int offset, unsigned short len)
{
    return S_NorFlash_Erase(norflash, offset, len);
}

signed char s_nor_flash_user_erase_page(unsigned short page)
{
    return S_NorFlash_Erase(norflash, FLASH_ADDRESS(page,0), norflash.sectorSize);
}

signed char s_nor_flash_user_read(unsigned int offset, unsigned char *data, unsigned short len)
{
    return S_NorFlash_Read(norflash, offset, data, len);;
}

signed char s_nor_flash_user_write(unsigned int offset, const unsigned char *data, unsigned short len)
{
    return S_NorFlash_Write(norflash, offset, data, len);;
}

signed char s_nor_flash_user_read_sectors(unsigned int sector_num, unsigned short sector_count, unsigned char *buf)
{
    unsigned short i = 0U;

    NorFlash_Result rslt = norflash_OK;

    if(NULL == buf) {
        // printf("read buff null\r\n");
        return -1;
    }

    for(; i < sector_count; i ++) {
        rslt = S_NorFlash_Read(norflash, sector_num * norflash.sectorSize, buf, norflash.sectorSize);
        sector_num++;
        if(norflash_OK != rslt) {
            break;
        }
    }

    return rslt;
}

signed char s_nor_flash_user_write_sectors(unsigned int sector_num, unsigned short sector_count, unsigned char *buf)
{
    unsigned short i = 0U;

    NorFlash_Result rslt = norflash_OK;

    for(; i < sector_count; i ++) {
        rslt = S_NorFlash_Erase(norflash, sector_num * norflash.sectorSize, norflash.sectorSize);
        rslt = S_NorFlash_Write(norflash, sector_num * norflash.sectorSize, buf, norflash.sectorSize);
        sector_num++;
        if(norflash_OK != rslt) {
            break;
        }
    }

    return rslt;
}

void s_nor_flash_user_test(void)
{
    signed char rslt = 0;
    unsigned char data[20], i;
    memset(data, 0x00, sizeof(data));

    rslt = s_nor_flash_user_open();
    printf("the open rst is %d\r\n", rslt);

    // while(1);

    s_nor_flash_user_erase_page(0x00);
    s_nor_flash_user_read(0x00, data, sizeof(data));
    for(i = 0; i < sizeof(data); i++)
    {
        printf("0x%02x, ", data[i]);
    }
    printf("\r\n");

    for(i = 0; i < sizeof(data); i++)
    {
        data[i] = i + 1;
    }
    s_nor_flash_user_write(0x00, data, sizeof(data));

    s_nor_flash_user_read(0x00, data, sizeof(data));
    for(i = 0; i < sizeof(data); i++)
    {
        printf("0x%02x, ", data[i]);
    }
    printf("\r\n");
    
    rslt = s_nor_flash_user_close();
    printf("the close rst is %d\r\n", rslt);
}
